package com.carey.blog.util;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;


import com.carey.blog.filter.PageCacheFilter;
import com.carey.blog.repository.ArticleRepository;
import com.carey.blog.repository.PageRepository;
import com.carey.blog.repository.impl.ArticleGAERepository;
import com.carey.blog.repository.impl.PageGAERepository;

/**
 * Permalink utilities.
 * 
 */
public final class Permalinks {

	/**
	 * Article repository.
	 */
	private ArticleRepository articleRepository = ArticleGAERepository
			.getInstance();
	/**
	 * Page repository.
	 */
	private PageRepository pageRepository = PageGAERepository.getInstance();
	/**
	 * Reserved permalinks.
	 */
	private static final Set<String> RESERVED_LINKS = new HashSet<String>();

	static {
		RESERVED_LINKS.add("/");
		RESERVED_LINKS.add("/index.do");
		RESERVED_LINKS.add("/article-detail.do");
		RESERVED_LINKS.add("/tag-articles.do");
		RESERVED_LINKS.add("/archive-date-articles.do");
		RESERVED_LINKS.add("/tags.do");
		RESERVED_LINKS.add("/tags.html");
		RESERVED_LINKS.add("/tags");
		RESERVED_LINKS.add("/page.do");
		RESERVED_LINKS.add("/blog-articles-feed.do");
		RESERVED_LINKS.add("/tag-articles-feed.do");
		RESERVED_LINKS.add("/captcha.do");
		RESERVED_LINKS.add("/error.do");
		RESERVED_LINKS.add("/file-access.do");
		RESERVED_LINKS.add("/datastore-file-access.do");

		RESERVED_LINKS.addAll(Arrays.asList(PageCacheFilter.ADMIN_ACTIONS));
	}

	/**
	 * Determines whether the specified permalink exists.
	 * 
	 * @param permalink
	 *            the specified permalink
	 * @return {@code true} if exists, returns {@code false} otherwise
	 */
	public boolean exist(final String permalink) {
		return isReserved(permalink)
				|| null != articleRepository.getByPermalink(permalink)
				|| null != pageRepository.getByPermalink(permalink)
				|| permalink.endsWith(".ftl");
	}

	/**
	 * Determines whether the specified permalink reserved.
	 * 
	 * @param permalink
	 *            the specified permalink
	 * @return {@code true} if reserved, returns {@code false} otherwise
	 */
	private boolean isReserved(final String permalink) {
		if ("/".equals(permalink)) {
			return true;
		}

		for (final String reservedLink : RESERVED_LINKS) {
			if ("/".equals(reservedLink)) {
				continue;
			}

			if (permalink.startsWith(reservedLink)) {
				return true;
			}
		}

		return false;
	}

	/**
	 * Gets the {@link Permalinks} singleton.
	 * 
	 * @return the singleton
	 */
	public static Permalinks getInstance() {
		return SingletonHolder.SINGLETON;
	}

	/**
	 * Private default constructor.
	 */
	private Permalinks() {
	}

	/**
	 * Singleton holder.
	 * 
	 */
	private static final class SingletonHolder {

		/**
		 * Singleton.
		 */
		private static final Permalinks SINGLETON = new Permalinks();

		/**
		 * Private default constructor.
		 */
		private SingletonHolder() {
		}
	}
}
